<?php

declare(strict_types=1);

namespace app\common\traits;

use app\common\service\pmm\FlowBillService;
use app\common\service\pmm\FlowBrowsingService;
use app\common\service\pmm\FlowLogService;
use app\common\service\pmm\FlowStepLogService;
use app\common\service\pmm\MessageService;
use app\common\service\hrm\FilesService;
use think\facade\Db;

/**
 * 流程公共业务方法
 * @author kaige
 * @update 2022-08-31
 * @copyright ©2022 泉州市盛筑信息科技有限公司 版权所有
 */
trait FlowServiceTrait
{
  /**
   * 添加、编辑数据保存
   * @param $data 前端载入
   * @param $user 用户信息
   * @param $sysdict 系统字典
   * @return array
   */
  public function saveData($data, $user, $sysdict)
  {
    $this->formatData($data); //公共--处理数据
    $this->moduformatData($data); // 各自模块处理数据 -- 预留
    $data['modu_id'] = $this->moduId; //各自模块 - 流程模块ID
    $fbs = new FlowBillService();
    $statustd = $sysdict['status_td']; //状态字典
    Db::startTrans();
    try {
      //处理保存前业务 -- 预留
      $befo_res = $this->_save_before($data);
      if (!$befo_res['status']) {
        Db::rollback();
        return $befo_res;
      }
      if (isset($data['id']) && !empty($data['id'])) { //编辑
        //取出
        $now = $this->dao->getflow($data['id']);
        //判断是不是操作人
        if ($now['handle_uid'] != $user['id']) {
          Db::rollback();
          return _err('不能编辑他人的流程');
        }
        //流程数据编排
        $flowdata = $fbs->flow_add_data($data, $user);
        //保存编辑流程表单
        $info = $this->dao->editflow($data, $flowdata);
        if (empty($info)) {
          Db::rollback();
          return _err('编辑流程数据时出错');
        }
        //保存子表明细业务
        $info1 = $this->_flow_save_after_item($data, $info);
        if ($info1 === false) {
          Db::rollback();
          return _err('保存明细回调时出错');
        }
        //更新流程及日志
        $info2 = $fbs->updateBill($data, $info, $statustd, $user);
        if ($info2 && $info2['status'] === false) { //输出 具体什么错误
          Db::rollback();
          return _err($info2['msg']);
        }
      } else { //添加
        $flowdata = $fbs->flow_add_data($data, $user);
        $info = $this->dao->addflow($data, $flowdata);
        if (empty($info)) {
          Db::rollback();
          return _err('添加流程数据时出错');
        }
        $info1 = $this->_flow_save_after_item($data, $info);
        if ($info1 === false) {
          Db::rollback();
          return _err('保存明细回调时出错');
        }
        $info2 = $fbs->updateBill($data, $info, $statustd, $user);
        if ($info2 && $info2['status'] === false) { //输出 具体什么错误
          Db::rollback();
          return _err($info2['msg']);
        }
        $info3 = $this->_save_add_next($data, $info);
        if ($info3 === false) {
          Db::rollback();
          return _err('添加保存之后回调时出错');
        }
      }
      if ($info && $info1 && $info2) {
        Db::commit();
      } else {
        Db::rollback();
      }
    } catch (\Exception $e) {
      Db::rollback();
    }
    $dztxt = '保存';
    if ($data['is_put'] == 3) {
      $dztxt = '撤回';
    }
    if ($info && $info1 && $info2) {
      return _ok($dztxt . '成功', [
        'id' => $info['id'],
        'info' => $info
      ]);
    }
    return _err($dztxt . '失败');
  }

  /**
   * 表单保存副表之后，保存子表明细业务
   * @param array $data 前端post过来的
   * @param array $info 副表保存后的
   * @return bool  返回TRUE 处理成功，false处理失败。使保存流程失败。 调用 $res = _flow_save_after_item($post)
   */
  public function _flow_save_after_item($data, $info)
  {
    return true;
  }

  /**
   * 保存添加之后回调
   */
  public function _save_add_next($data, $info)
  {
    return true;
  }

  /**
   * 保存前，业务处理,如果要中断，返回 _err()
   */
  public function _save_before($data)
  {
    return _ok();
  }

  /**
   * 格式化存储的数据--各模块的
   * @return void
   */
  public function moduformatData(&$data)
  {
    //to do ....
  }

  /**
   * 格式化存储的数据--存储
   * @return void
   */
  public function formatData(&$data)
  {
    if (isset($data['is_put'])) {
      if ($data['is_put'] == 1 && $data['status'] < 2) {
        $data['status'] = 1;
      }
      if ($data['is_put'] == 2 || $data['is_put'] == 3) {
        $data['status'] = 0;
      }
    }
  }
  /**
   * 删除
   */
  public function deleteFlow($id = 0, $user = [])
  {
    $now = $this->dao->getflow($id);
    //判断是不是操作人
    if ($now['handle_uid'] !== $user['id']) {
      return false;
    }
    if ($now) {
      if ($now['status'] < 1) {
        //删除流程
        (new FlowBillService())->deleteByWhere(['modu_id' => $this->moduId, 'id' => $id]);
        //删除记录
        (new FlowLogService())->deleteByWhere(['modu_id' => $this->moduId, 'm_id' => $id]);
        //删除步骤副本记录
        (new FlowStepLogService())->deleteByWhere(['modu_id' => $this->moduId, 'm_id' => $id]);
        //删除浏览记录
        (new FlowBrowsingService())->deleteByWhere(['modu_id' => $this->moduId, 'm_id' => $id]);
        //删除相关文件
        FilesService::del([
          'table_name' => $now['table'],
          'table_id' => $id,
          'files_id' => 'all'
        ]);
        //删除通知消息
        (new MessageService())->deleteByWhere(['modu_id' => $this->moduId, 'm_id' => $id]);
        //删除自个
        $this->dao->delete($id);
        return true;
      }
    }
    return false;
  }

  /**
   * 流程结束时回调,只是执行过程，无返回状态，需保证程序的正确性。
   */
  public function _audit_allok($data, $user)
  {
    //逻辑代码...
    //如果该模块没有回调，放空即可。否则重写该方法即可。

  }
}
